extends Object

class_name Cell

var iii = 0
var jjj = 0

var neighbors = []
var type = null
var individuum = null

var field_vector = []
var future_field_vector = []

var room = null

func _init():
	for i in CellType.SIGNAL_COUNT:
		field_vector.append(0.0)

func calculate_field():
	future_field_vector = Array() #creating _new_ object
	#print("calculating at", Vector2(iii,jjj))
	for i in range(CellType.SIGNAL_COUNT):
		future_field_vector.append(0)



	for n in neighbors:
		for s in range(CellType.SIGNAL_COUNT):
			future_field_vector[s] += n.field_vector[s]

	#print("external sum is", future_field_vector)

	future_field_vector = type.mix(future_field_vector)

	#print ("after mixing", future_field_vector)
#
#	for n in neighbors:
#		var field = type.mix(n.field_vector)
#		for s in range(CellType.SIGNAL_COUNT):
#			future_field_vector[s] += field[s]

	for s in range(CellType.SIGNAL_COUNT):
		future_field_vector[s] += type.own_production[s]
		future_field_vector[s] = clamp(future_field_vector[s], -type.FIELD_CAP, type.FIELD_CAP)

	#print ("after production and clamping")

	#print ("calculate: returning \n", future_field_vector)

func apply_field():
	field_vector.clear()
	field_vector = future_field_vector # passing by reference (ffv is created anew all the time)


func proliferate(): #returns true if proliferation occurs

	for i in range(CellType.types.size()):
		var proliferating = true
		for s in range(CellType.SIGNAL_COUNT):
			var value = field_vector[s]
			if not (value >= type.proliferations[i].min_ranges[s]
					and value <= type.proliferations[i].max_ranges[s]):
						#print("not proliferating ", s, " is out of range")
						#print(type.proliferations[i].min_ranges[s] ," ", value, " ", type.proliferations[i].max_ranges[s])
						proliferating = false
		if proliferating:
			var future_type = i
			var current_type_index = type.type_index
			if i != current_type_index: #only need to break the loop if morphing into sth else
				#print("CHANGING INTO STH")
				type = individuum.types[future_type]
				return true
	return false
